package ne.aishuyuan.video.view;

import lombok.extern.slf4j.Slf4j;
import ne.aishuyuan.video.bean.Media;
import ne.aishuyuan.video.bean.NetworkMedia;
import ne.aishuyuan.video.bean.PlayMedia;
import ne.aishuyuan.video.service.LoadResourceService;
import ne.aishuyuan.video.utils.DeviceInfoUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.EnableScheduling;
import oshi.SystemInfo;
import oshi.hardware.HardwareAbstractionLayer;
import uk.co.caprica.vlcj.player.base.Marquee;
import uk.co.caprica.vlcj.player.base.MarqueePosition;
import uk.co.caprica.vlcj.player.base.MediaPlayer;
import uk.co.caprica.vlcj.player.base.MediaPlayerEventAdapter;
import uk.co.caprica.vlcj.player.component.EmbeddedMediaPlayerComponent;
import uk.co.caprica.vlcj.player.embedded.fullscreen.adaptive.AdaptiveFullScreenStrategy;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.io.File;
import java.io.IOException;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;


/**
 * @ClassName: Player
 * @Description: vlcj 播放器
 * @Author: clj
 * @Date: 2021/11/2 16:09
 */
@Slf4j
@EnableScheduling
public class Player extends JFrame {

	private JFrame frame;
	private EmbeddedMediaPlayerComponent mediaPlayerComponent;
	private JPanel contentPane;
	private JPanel controlsPane;
	private Media currentMedia;
	//实际播放清单
	private PlayMedia playMedia;
	//固定播放清单
	private PlayMedia fixedPlayMedia;
	//定时播放清单
	private PlayMedia timerPlayMedia;
	//插播播放清单
	private PlayMedia insertPlayMedia;

	//实际播放列表
	private JComboBox<Media> mediaList;
	//固定播放列表
	private JComboBox<Media> fixedMediaList;
	//定时播放列表
	private JComboBox<Media> timerMediaList;
	//插播播放列表
	private JComboBox<Media> insertMediaList;

	private JButton loadListButton,playNowButton, updateInfo;
	private JTextField text1,text2,text3;

	@Autowired
	private LoadResourceService loadResourceService;
	//当前播放标志 0：固定播放 fixed    1：定时播放timer      2:插播
	private int playRule;

    public  Player() {
		frame = new JFrame();
        frame.setBounds(500, 500, 600, 400);
        frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
        frame.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                mediaPlayerComponent.release();
                System.exit(0);
            }
        });
        JPanel contentPane = setContentPane();
        addListener();
        frame.setContentPane(contentPane);
		frame.setVisible(true);
		try {
			config();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 创建内容面板
	 * @param
	 * @return javax.swing.JPanel
	 */
	private JPanel setContentPane() {
		contentPane = new JPanel();
        contentPane.setLayout(new BorderLayout());
		mediaPlayerComponent = new EmbeddedMediaPlayerComponent() {
			@Override
			public void mouseClicked(MouseEvent  e) {
				//鼠标双击
				if (e.getClickCount() == 2) {
					mediaPlayerComponent.mediaPlayer().fullScreen().toggle();
					mediaList.setVisible(false);
					controlsPane.setVisible(false);
				}
			}
			@Override
			public void mouseWheelMoved(MouseWheelEvent e) {
			}
			//键盘事件
			@Override
			public void keyPressed(KeyEvent e) {
				if (e.getKeyCode() == KeyEvent.VK_ESCAPE ) {
					mediaPlayerComponent.mediaPlayer().fullScreen().set(false);
					controlsPane.setVisible(true);
					mediaList.setVisible(true);
				}
				if (e.getKeyCode() == KeyEvent.VK_Q ) {
					mediaPlayerComponent.release();
					System.exit(0);
				}
			}
		};
		contentPane.add(mediaPlayerComponent,BorderLayout.CENTER);
		//播放控制面板
		controlsPane = new JPanel();
		loadListButton = new JButton("加载播放列表");
		controlsPane.add(loadListButton);
		playNowButton = new JButton("插播");
		controlsPane.add(playNowButton);
		//调试代码
		updateInfo = new JButton("更新设备信息");
		SystemInfo si = new SystemInfo();
		HardwareAbstractionLayer hal = si.getHardware();
	 	text1 = new JTextField("getSerialNumber="+ DeviceInfoUtil.getSerialNumber());
	 	text2 = new JTextField("HardwareUUID="+ DeviceInfoUtil.getHardwareUUID());
	 	text3 = new JTextField("processorID="+ DeviceInfoUtil.getProcessorID());
		controlsPane.add(updateInfo);
		controlsPane.add(text1);
		controlsPane.add(text2);
		controlsPane.add(text3);
		contentPane.add(controlsPane, BorderLayout.SOUTH);
		mediaPlayerComponent.mediaPlayer().fullScreen().strategy(new AdaptiveFullScreenStrategy(frame));
		mediaList = new JComboBox<>();
		fixedMediaList = new JComboBox<>();
		timerMediaList = new JComboBox<>();
		insertMediaList = new JComboBox<>();
		contentPane.add(mediaList,BorderLayout.NORTH);
		return contentPane;
    }

    /**
     * 事件
     * @param []
     * @return void
     */
    private void addListener() {
		updateInfo.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				SystemInfo si = new SystemInfo();
				HardwareAbstractionLayer hal = si.getHardware();
				text1 = new JTextField("getSerialNumber="+ DeviceInfoUtil.getSerialNumber() );
				text2 = new JTextField("HardwareUUID="+ DeviceInfoUtil.getHardwareUUID());
				text3 = new JTextField("processorID="+ DeviceInfoUtil.getProcessorID());
			}
		});

    	//加载资源
		loadListButton.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				load();
			}
		});

		//插播 -- 调试代码 后续删除
		playNowButton.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				insertPlayMedia = new PlayMedia();
				insertPlayMedia.setType("LIVE");
				insertPlayMedia.setPlayPattern("ORDERED");
				insertPlayMedia.setPlayRule("RIGHTNOW");
				List<Media> resources = new ArrayList<>();
				Media media1 = new Media("http://192.168.1.54:9000/aisy/20211111/16366189874490f3969c5-c65f-4484-affb-dbe8038e6701.mp4","http://192.168.1.54:9000/aisy/20211111/16366189874490f3969c5-c65f-4484-affb-dbe8038e6701.mp4",5,"1");
				media1.setType("VIDEO");
				media1.setPlayType("LIVE");
				Media media2 = new Media("http://192.168.1.54:9000/aisy/20211111/16366190283222c000031-05e5-437a-82df-84d2d240d753.mp4","http://192.168.1.54:9000/aisy/20211111/16366190283222c000031-05e5-437a-82df-84d2d240d753.mp4",5,"1");
				media2.setType("VIDEO");
				media2.setPlayType("LIVE");
				resources.add(media1);
				resources.add(media2);
				insertPlayMedia.setResourceVos(resources);
				loadInsert(insertPlayMedia);
			}
		});
    	//播放列表切换事件
        mediaList.addItemListener(new ItemListener() {
			@Override
			public void itemStateChanged(ItemEvent e) {
				currentMedia=(Media) e.getItem();
				String url = currentMedia.getUrl();
				//本地播放
				if (currentMedia.getPlayType().equals("LOCAL_PLAY")) {
					url = currentMedia.getPath() + File.separator + url.substring(url.lastIndexOf("/"));
				}
				long playTime = currentMedia.getDuration() == null ?0:currentMedia.getDuration();
				log.debug("自动切换>>>>>>>>>>>>>>>>>>>>>>>当前播放路径，{}，播放时长，{}",url,playTime);
				if (currentMedia.getType().equals("VIDEO")) {
					mediaPlayerComponent.mediaPlayer().media().play(url);
					if (playTime == 0) {
						mediaPlayerComponent.mediaPlayer().media().play(url);
					} else {
						mediaPlayerComponent.mediaPlayer().media().play(url, "run-time="+playTime);
					}
				} else {
					if ( playTime == 0) {
						mediaPlayerComponent.mediaPlayer().media().play(url);
					} else {
						mediaPlayerComponent.mediaPlayer().media().play(url, "run-time="+playTime);
					}
				}
			}
        });
        mediaPlayerComponent.mediaPlayer().events().addMediaPlayerEventListener(
        		new MediaPlayerEventAdapter() {
        		    @Override
        		    public void playing(MediaPlayer mediaPlayer) {
        		    	SwingUtilities.invokeLater(new Runnable() {
							@Override
							public void run() {
							}
        		    	});
        		    }
        		    @Override
        		    public void finished(MediaPlayer mediaPlayer) {
        		    	mediaPlayer.submit(new Runnable() {
							@Override
							public void run() {
								//根据当前时间加载播放列表
								getPlayRule();
								//顺序播放
								int index = mediaList.getSelectedIndex();
								int max = mediaList.getItemCount();
								if(index + 1 == max) {
									//插播完毕
									if (playRule == 2) {
										getInsertPlayRule();
									} else {
										mediaList.setSelectedIndex(0);
									}
								} else {
									mediaList.setSelectedIndex(index + 1);
								}
							}
						});
        		    }

        		    @Override
        		    public void error(MediaPlayer mediaPlayer) {
        		    	SwingUtilities.invokeLater(new Runnable() {
							@Override
							public void run() {
								JOptionPane.showMessageDialog(
										frame,
										"Failed to play media",
										"播放失败",
						                JOptionPane.ERROR_MESSAGE);
								frame.dispatchEvent(new WindowEvent(frame, WindowEvent.WINDOW_CLOSING));
							}
        		    	});
        		    }
        	    }
        	);
    }


    /**
     *  根据定时间判断是否定时播放
     * @param []
     * @return void
     */
    private void getPlayRule() {
		if (null != timerPlayMedia) {
			LocalDateTime startTime = timerPlayMedia.getPlayStartTime();
			LocalDateTime endTime = timerPlayMedia.getPlayEndTime();
			LocalDateTime date = LocalDateTime.now();
			//定时播放
			if (date.isAfter(startTime) && date.isBefore(endTime) && playRule == 0) {
				playMedia = timerPlayMedia;
				playRule = 1;
				mediaList.removeAllItems();
				for (int i =0 ;i < timerMediaList.getItemCount();i++) {
					mediaList.addItem(timerMediaList.getItemAt(i));
				}
				mediaList.setSelectedIndex(0);
				//固定播放
			} else if ((date.isBefore(startTime) || date.isAfter(endTime)) && playRule == 1) {
				playMedia = fixedPlayMedia;
				playRule = 0;
				mediaList.removeAllItems();
				for (int i =0 ;i < fixedMediaList.getItemCount();i++) {
					mediaList.addItem(fixedMediaList.getItemAt(i));
				}
				mediaList.setSelectedIndex(0);
			}
		}
	}
	/**
	 *  插播完毕后规则判断
	 * @param []
	 * @return void
	 */
	private void getInsertPlayRule() {
		if (null != timerPlayMedia) {
			LocalDateTime startTime = timerPlayMedia.getPlayStartTime();
			LocalDateTime endTime = timerPlayMedia.getPlayEndTime();
			LocalDateTime date = LocalDateTime.now();
			//定时播放
			if (date.isAfter(startTime) && date.isBefore(endTime) ) {
				playMedia = timerPlayMedia;
				playRule = 1;
				mediaList.removeAllItems();
				for (int i =0 ;i < timerMediaList.getItemCount();i++) {
					mediaList.addItem(timerMediaList.getItemAt(i));
				}
				mediaList.setSelectedIndex(0);
				//固定播放
			} else if ((date.isBefore(startTime) || date.isAfter(endTime))) {
				playMedia = fixedPlayMedia;
				playRule = 0;
				mediaList.removeAllItems();
				for (int i =0 ;i < fixedMediaList.getItemCount();i++) {
					mediaList.addItem(fixedMediaList.getItemAt(i));
				}
				mediaList.setSelectedIndex(0);
			}
		}
	}

    /**
     * 加载资源
     * @param []
     * @return void
     */
    public void load() {
		new Thread(() -> {
			NetworkMedia networkMedia =  loadResourceService.loadMedia(mediaList,fixedMediaList,timerMediaList);
			playMedia = networkMedia.getPlayMedia();
			fixedPlayMedia = networkMedia.getFixedPlayMedia();
			timerPlayMedia = networkMedia.getTimerPlayMedia();
			controlsPane.setVisible(false);
			mediaList.setVisible(false);
			mediaPlayerComponent.mediaPlayer().fullScreen().set(true);
		}).start();
	}

	/**
	 * 插播
	 * @param []
	 * @return void
	 */
	public void loadInsert(PlayMedia insertPlayMedia) {
		//更改插播标志
		playRule = 2;
		this.insertPlayMedia = insertPlayMedia;
		List<Media> resourceVos = insertPlayMedia.getResourceVos();
		insertMediaList.removeAllItems();
		resourceVos.stream().forEach(item -> {
			insertMediaList.addItem(item);
		});
		playMedia = insertPlayMedia;
		mediaList.removeAllItems();
		for (int i =0 ;i < insertMediaList.getItemCount();i++) {
			mediaList.addItem(insertMediaList.getItemAt(i));
		}
		mediaList.setSelectedIndex(0);
		controlsPane.setVisible(false);
		mediaList.setVisible(false);
	}



	/**
	 * 暂停播放
	 * @param []
	 * @return void
	 */
	public void  pause() {
		mediaPlayerComponent.mediaPlayer().controls().pause();
	}

	/**
	 * 暂停播放
	 * @param []
	 * @return void
	 */
	public void  stop() {
		mediaPlayerComponent.mediaPlayer().controls().stop();
	}

	/**
	 * 暂停播放
	 * @param []
	 * @return void
	 */
	public void  start() {
		mediaPlayerComponent.mediaPlayer().controls().start();
	}

	/**
     * 装饰配置
     */
    private void config() throws IOException {
		//字幕功能
		Marquee marquee = Marquee.marquee()
				.text("AI书院媒体播放器")
				.size(30)
				.colour(Color.WHITE)
				.timeout(10000)
				.position(MarqueePosition.TOP_LEFT)
				.opacity(0.3f)
				.enable();
		mediaPlayerComponent.mediaPlayer().marquee().set(marquee);
	}
}

